﻿using Org.BouncyCastle.Crypto;
using ProTrack.Dto;
using ProTrack.Entity;
using ProTrack.IRepository;
using ProTrack.IServices.PurchaseOrder;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace ProTrack.Services.PurchaseOrder
{
    public class WareHouseInboundBillServices : IWareHouseInboundBillServices
    {
        public WareHouseInboundBillServices(IBaseRepository db) 
        {
            Db = db;
        }

        public IBaseRepository Db { get; }

        public async Task<bool> AddAsync(WareHouseInboundBill model, List<WareHouseInboundBillItem> list)
        {
            var result = await Db.InsertIdentityTranAsync(model, list);

            if (result)
            {
                var count = await GetOrderPoByItemCount(model.OrderPoId);
                if (count <= 0)
                {
                    //全部到货
                    await Db.UpdateAsync("update OrderPo set State=2 where Id=@Id", new { Id = model.OrderPoId });
                }
                else
                {
                    //部分到货
                    await Db.UpdateAsync("update OrderPo set State=1 where Id=@Id", new { Id = model.OrderPoId });
                }
            }

            return result;
        }

        class WareHouseInboundBillIds
        {
            public int OrderPoId { get; set; }
        }
        public async Task<bool> DeleteAsync(int[] Ids)
        {

            string putSql = @" update OrderPo set State=0  where Id in (select OrderPoId from WareHouseInboundBill where Id in @Ids)";
            await Db.UpdateAsync(putSql, new { Ids });

            var list = await Db.QueryAsync<WareHouseInboundBillIds>("select OrderPoId from WareHouseInboundBill where OrderPoId in(select OrderPoId from  WareHouseInboundBill where Id in @Ids)", new {Ids});

            string sql = "delete WareHouseInboundBill where Id in @Ids;delete WareHouseInboundBillItem where WareHouseInboundBillId in @Ids;";
            var result = await Db.DeleteAsync(sql, new { Ids });

            if (result)
            {

                putSql = @" update OrderPo set State=1  where Id in (select OrderPoId from WareHouseInboundBill  where OrderPoId = @OrderPoId)";
                await Db.UpdateAsync(putSql, list);

            }



            return result;
        }

        public async Task<IEnumerable<WareHouseInboundBill>> GetAllAsync()
        {
            string sql = "select * from WareHouseInboundBill";
            var list = await Db.QueryAllAsync<WareHouseInboundBill>(sql);
            return list;
        }

        public async  Task<IEnumerable<WareHouseInboundBill>> GetAsync(int PageIndex, int PageSize, string Number, string VendorId, string WareHouseId, int Status)
        {
            string sql = "select * from WareHouseInboundBill where 1=1 ";
            if (!string.IsNullOrEmpty(Number))
            {
                sql += " and Number like @Number ";
            }
            if (!string.IsNullOrEmpty(VendorId))
            {
                sql += " and VendorId like @VendorId ";
            }
            if (!string.IsNullOrEmpty(WareHouseId))
            {
                sql += " and WareHouseId like @WareHouseId ";
            }
            if (Status != -1)
            {
                sql += " and Status =@Status";
            }

            sql += " order by CreateTime desc offset @PageSize*(@PageIndex-1) row fetch next @PageSize rows only";

            var list = await Db.QueryAsync<WareHouseInboundBill>(sql, new { PageIndex, PageSize, Number = $"%{Number}%", VendorId = $"%{VendorId}%", WareHouseId = $"%{WareHouseId}%", Status });
            return list;
        }

        public async Task<int> GetCountAsync(string Number, string VendorId, string WareHouseId, int Status)
        {
            string sql = "select count(*) from OrderPo where 1=1 ";
            if (!string.IsNullOrEmpty(Number))
            {
                sql += " and Number like @Number ";
            }
            if (!string.IsNullOrEmpty(VendorId))
            {
                sql += " and VendorId like @VendorId ";
            }
            if (!string.IsNullOrEmpty(WareHouseId))
            {
                sql += " and WareHouseId like @WareHouseId";
            }
            if (Status != -1)
            {
                sql += " and Status =@Status";
            }

            var list = await Db.GetRecoreCountAsync(sql, new { Number = $"%{Number}%", VendorId = $"%{VendorId}%", WarehouseId = $"%{WareHouseId}%", Status });
            return list;
        }

        public async  Task<IEnumerable<WareHouseInboundBillItemDto>> GetWareHouseInboundBillIdAsync(string WareHouseInboundBillId)
        {
            var list = await Db.QueryAsync<WareHouseInboundBillItemDto>(
                @"select item.Spec,item.ItemName,item.ItemCode,item.UnitOfMeasure,item.Model,wh.*,(
	                    select Count from OrderPoItem where OrderPoId=wi.OrderPoId and ItemId=wh.ItemId
                    ) as Count
                    from WareHouseInboundBillItem wh inner join Item item on wh.ItemId=item.Id
                    inner join WareHouseInboundBill wi on wi.Id=wh.WareHouseInboundBillId
                    where wh.WareHouseInboundBillId = @WareHouseInboundBillId", new { WareHouseInboundBillId});
            return list;
        }

        public async Task<IEnumerable<WareHouseInboundBillItemDto>> GetOrderPoByItem(string OrderPoId)
        {
            var list = await Db.QueryAsync<WareHouseInboundBillItemDto>(
                @"
	            with tab as(	
		            select 
			            ISNULL((select sum(Quantity) from WareHouseInboundBillItem wbi  inner join  WareHouseInboundBill wb on wb.Id=wbi.WareHouseInboundBillId where wbi.ItemId=opi.ItemId and wb.OrderPoId=@OrderPoId   ),0) as Quantity ,opi.Count,opi.ItemId,opi.TaxPrice,opi.TaxAmount,opi.Price,opi.Amount
		            from OrderPoItem opi where OrderPoId=@OrderPoId
	            )
	            select Count-tab.Quantity as Count,ItemId,Amount,Price,TaxAmount,TaxPrice,im.ItemName,im.Spec,im.UnitOfMeasure,im.Model,im.ItemCode from tab
	            inner join Item im on im.Id = tab.ItemId
	            where (Count-tab.Quantity) >0", new { OrderPoId });
            return list;
        }

        private async Task<int> GetOrderPoByItemCount(long OrderPoId)
        {
            var count = await Db.GetRecoreCountAsync(
             @"
	            with tab as(	
		            select 
			            ISNULL((select sum(Quantity) from WareHouseInboundBillItem wbi  inner join  WareHouseInboundBill wb on wb.Id=wbi.WareHouseInboundBillId where wbi.ItemId=opi.ItemId and wb.OrderPoId=@OrderPoId   ),0) as Quantity ,opi.Count,opi.ItemId,opi.TaxPrice,opi.TaxAmount,opi.Price,opi.Amount
		            from OrderPoItem opi where OrderPoId=@OrderPoId
	            )
	            select count(*) as Count from tab  where (Count-tab.Quantity) >0
            ", new { OrderPoId });
            return count;
        }

        public async Task<bool> UpdateAsync(WareHouseInboundBill model, List<WareHouseInboundBillItem> list)
        {
            var result = await Db.UpdateIdentityTranAsync(model, list);
            if (result)
            {
                var count = await GetOrderPoByItemCount(model.OrderPoId);
                if (count <= 0)
                {
                    //全部到货
                    await Db.UpdateAsync("update OrderPo set State=2 where Id=@Id", new { Id = model.OrderPoId });
                }
                else
                {
                    //部分到货
                    await Db.UpdateAsync("update OrderPo set State=1 where Id=@Id", new { Id = model.OrderPoId });
                }
            }
         
            return result;
        }

        public async  Task<bool> UpdateWareHouseInboundBillStatus(long Id, int Status)
        {
            string sql = $"update WareHouseInboundBill set Status=@Status where Id =@Id";
            var result = await Db.UpdateAsync(sql, new { Id, Status });
            return result;
        }
    }
}
